package com.wg.generator.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson.JSON;
import com.wg.generator.config.Constants;
import com.wg.generator.entity.DownloadParam;
import com.wg.generator.entity.TemplateConfig;
import com.wg.generator.util.FreemarkerUtil;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * service impl
 *
 * @author lihc14
 */
@Slf4j
@Service
public class GeneratorServiceImpl implements GeneratorService {

    @Autowired
    private FreemarkerUtil freemarkerTool;

    String templateCpnfig = null;

    private String getTemplateConfig() throws IOException {
        templateCpnfig = null;
        if (templateCpnfig != null) {
        } else {
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template.json");
            templateCpnfig = new BufferedReader(new InputStreamReader(inputStream))
                    .lines().collect(Collectors.joining(System.lineSeparator()));
            inputStream.close();
        }
        //log.info(JSON.toJSONString(templateCpnfig));
        return templateCpnfig;
    }


    /**
     * 根据配置的Template模板进行遍历解析，得到生成好的String
     */
    @Override
    public Map<String, String> getResultByParams(Map<String, Object> params, HttpServletRequest request) throws IOException, TemplateException {
        Map<String, String> result = new LinkedHashMap<>(32);
        result.put("tableName", params.get("tableName") + "");
        List<TemplateConfig> templateConfigList = JSON.parseArray(getTemplateConfig(), TemplateConfig.class);
        for (TemplateConfig item : templateConfigList) {
            result.put(item.getName(), freemarkerTool.processString(item.getGroup() + "/" + item.getName() + ".ftl", params));
        }
        Constants.CODE_MAP.put(ServletUtil.getClientIP(request), result);
        return result;
    }

    @Override
    public String downloadFile(DownloadParam downloadParam, HttpServletRequest request) {
        String clientIp = ServletUtil.getClientIP(request);
        Map<String, String> result = Constants.CODE_MAP.get(clientIp);
        if (result == null) {
            return "请先生成代码后再下载";
        }
        if (StrUtil.isBlank(downloadParam.getDownloadPath())) {
            return "请先生设置下载路径";
        }
        String packageStr = "code";
        String zipFolderPath = FileUtil.normalize(downloadParam.getDownloadPath().concat(StrUtil.BACKSLASH).concat(packageStr));
        String zipFilePath = FileUtil.normalize(downloadParam.getDownloadPath().concat(StrUtil.BACKSLASH).concat(clientIp).concat(packageStr).concat(".zip"));
        if (StrUtil.equals(downloadParam.getDownloadType(), "Z")) {
            FileUtil.del(zipFolderPath);
            FileUtil.del(zipFilePath);
            File folder = new File(zipFolderPath);
            if (!folder.exists()) {
                folder.mkdirs();
            }
        }

        for (Map.Entry<String, String> entry : result.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if(StrUtil.equalsAny(key, "tableName" , "beanUtil", "json")){
                continue;
            }
            int index1 = value.indexOf("package ");
            if (StrUtil.equals(downloadParam.getDownloadType(), "G")) {
                if (index1 > -1) {
                    packageStr = getPackagePath(value.substring(index1 + 8));
                }

                String folderPath = FileUtil.normalize(downloadParam.getDownloadPath().concat(StrUtil.BACKSLASH).concat(packageStr));
                String fileName = getFileName(key, value);
                File folder = new File(folderPath);
                if (!folder.exists()) {
                    folder.mkdirs();
                }
                String filePath = folderPath.concat(StrUtil.BACKSLASH).concat(fileName);
                File file = new File(filePath);
                if (!downloadParam.getOverwrite()) {
                    if (file.exists()) {
                        continue;
                    }
                }
                FileUtil.writeString(value, file, "utf-8");
            }

            if (StrUtil.equals(downloadParam.getDownloadType(), "Z")) {
                String fileName = getFileName(key, value);
                String filePath = zipFolderPath.concat(StrUtil.BACKSLASH).concat(fileName);
                FileUtil.writeString(value, new File(filePath), "utf-8");
            }
        }
        if (StrUtil.equals(downloadParam.getDownloadType(), "Z")) {
            ZipUtil.zip(zipFolderPath, zipFilePath);
            FileUtil.del(zipFolderPath);
        }

        return null;
    }

    private String getPackagePath(String value) {
        int index = value.indexOf(";");
        String packageStr = value.substring(0, index);
        return packageStr.replaceAll("\\.", "\\\\");
    }

    private String getFileName(String key, String value) {
        int index1 = -1;
        if(StrUtil.equalsAny(key, "plusmapper", "daoservice", "service")){
            index1 = value.indexOf("public interface ");
            value = value.substring(index1 + 17);
        }else {
            index1 = value.indexOf("public class ");
            value = value.substring(index1 + 13);
        }
        if(index1 == -1){
            return key.concat(".class_not_find").concat(".txt");
        }
        int index2 = value.indexOf(" ");
        return value.substring(0, index2).concat(".java");
    }
}
